﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Runtime.InteropServices;
using System.Text;
using up6.db.database.up6.mongo;
using up6.db.model;
using up6.db.sql;
using up6.db.utils;
using up6.sql;
using up6.utils;
using Up6.core.Up6Manager.Models;

namespace up6.db.database.up6.sql
{
    /// <summary>
    /// 数据库访问操作
    /// 更新记录：
    ///     2022-12-10 
    ///       完善read方法
    ///       删除exist_file
    ///		2014-03-11 将OleDb对象全部改为使用DbHelper对象，简化代码。
    ///		2012-04-10 创建
    /// </summary>
    public class SqlFile
    {
        public static SqlFile build()
        {
            var tp = ConfigReader.dbType();
            if (tp == DataBaseType.Kingbase || tp == DataBaseType.ODBC) return new up6.odbc.OdbcFile();
            if (tp == DataBaseType.MongoDB) return new MongoFile();
            else return new up6.sql.SqlFile();
        }
        
        public virtual FileInf read(string f_id)
        {
            var f = SqlTable.build("up6_files").readOne<FileInf>(SqlWhere.build().eq("f_id", f_id));
            return f;
        }

        public virtual FileInf read(string pathRel,string id,string uid)
        {
            return SqlTable.build("up6_files").readOne<FileInf>("f_id,f_pid,f_pidRoot,f_pathSvr,f_pathRel",
                SqlWhere.build()
                .eq("f_pathRel", pathRel)
                .eq("f_deleted", false)
                .eq("f_uid", uid)
                .ineq("f_id", id)
                );
        }

        public virtual FileInf exist_file(string md5)
        {
            if(string.IsNullOrEmpty(md5)) return null;
            SqlTable t = new SqlTable("up6_files");
            var o = t.readOne<FileInf>(SqlWhere.build()
                .eq("f_md5", md5)
                .eq("f_complete", true));
            return o;
        }

        /// <summary>
        /// 增加一条数据，并返回新增数据的ID
        /// 在ajax_create_fid.aspx中调用
        /// 文件名称，本地路径，远程路径，相对路径都使用原始字符串。
        /// d:\soft\QQ2012.exe
        /// </summary>
        public virtual void Add(FileInf f)
        {
            SqlTable.build("up6_files").insert(f);
        }

        public virtual void Clear()
        {
            var t = new SqlTable("up6_files");
            t.clear();
            var fd = new SqlTable("up6_folders");
            fd.clear();
        }

        /// <summary>
        /// 更新上传进度
        /// </summary>
        ///<param name="f_uid">用户ID</param>
        ///<param name="f_id">文件ID</param>
        ///<param name="f_pos">文件位置，大小可能超过2G，所以需要使用long保存</param>
        ///<param name="f_lenSvr">已上传长度，文件大小可能超过2G，所以需要使用long保存</param>
        ///<param name="f_perSvr">已上传百分比</param>
        public virtual bool process(string f_uid, string f_id, long offset, long f_lenSvr, string f_perSvr)
        {
            var t = new SqlTable("up6_files");
            t.update(SqlSeter.build().set("f_pos", offset)
                .set("f_lenSvr", f_lenSvr)
                .set("f_perSvr", f_perSvr),
                SqlWhere.build()
                .eq("f_uid", f_uid)
                .eq("f_id", f_id));

            return true;
        }

        public virtual void complete(string id)
        {
            SqlTable.build("up6_files").update(
                SqlSeter.build()
                .sql("f_lenSvr=f_lenLoc")
                .set("f_perSvr", "100%")
                .set("f_complete", true)
                .set("f_scan", true),
                SqlWhere.build().eq("f_id", id)
                );
        }

        /// <summary>
        /// 删除一条数据，并不真正删除，只更新删除标识。
        /// </summary>
        /// <param name="f_uid"></param>
        /// <param name="f_id"></param>
        public virtual void Delete(string f_uid, string f_id)
        {
            SqlTable.build("up6_files").update(
                SqlSeter.build()
                .set("f_deleted", true),
                SqlWhere.build()
                .eq("f_id",f_id)
                .eq("f_uid",f_uid)
                );
        }

        /// <summary>
        /// 根据相对路径删除同名文件
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="name"></param>
        /// <param name="uid"></param>
        /// <param name="id"></param>
        public virtual void delete(string pathRel, string uid,string id)
        {
            SqlTable.build("up6_files").update(
                SqlSeter.build()
                .set("f_deleted", true),
                SqlWhere.build()
                .eq("f_uid", uid)
                .eq("f_pathRel", pathRel)
                .eq("f_fdTask",false)
                .ineq("f_id", id)
                );
        }

        /// <summary>
        /// 获取未完成的文件列表
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public virtual string uncmps(string uid) {

            var fs = SqlTable.build("up6_files")
                .reads<FileInf>(SqlWhere.build().eq("f_uid", uid)
                .eq("f_complete", false)
                .eq("f_deleted", false)
                .eq("f_fdChild", false)
                .eq("f_scan", false));

            return JsonConvert.SerializeObject(fs);
        }

        public virtual void addBatch(List<FileInf> fs)
        {
            SqlTable.build("up6_files").inserts<FileInf>(fs);
        }
    }
}